package com.demo.java.OD151_200.OD189;

import java.util.ArrayList;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Scanner;

/**
 * @author bug菌
 * @Source 公众号：猿圈奇妙屋
 * @des： 【最小叶子节点】问题
 * @url： https://blog.csdn.net/weixin_43970743/article/details/145882152
 */
public class OdMain {
    public static void main(String[] args) {
        try (Scanner s = new Scanner(System.in)) {
            String ts = s.nextLine(); // 读取一行输入
            solveMethod(ts); // 调用 solveMethod 处理
        }
    }

    // 回溯路径
    private static void back(String[] split, int minPos, List<String> path) {
        path.add(split[minPos]); // 将当前节点加入路径
        if (minPos == 1) { // 如果是根节点，结束递归
            return;
        }
        // 如果不是根节点，递归回溯到父节点
        back(split, minPos % 2 == 0 ? minPos / 2 : (minPos - 1) / 2, path);
    }

    // 处理输入并找到最小叶子节点路径
    private static void solveMethod(String ts) {
        String[] split = ("0 " + ts).split(" "); // 将输入的字符串分割成数组，根节点前加上 0
        PriorityQueue<Integer> heap = new PriorityQueue<>(); // 最小堆，用来存储所有非零非-1的节点值
        // 遍历每个节点，加入最小堆
        for (int i = 2; i < split.length; ++i) {
            int tmp = Integer.parseInt(split[i]);
            if (tmp != 0 && tmp != -1) {
                heap.offer(tmp); // 加入堆
            }
        }
        int min = heap.peek(); // 获取堆中的最小值
        int minPos = 0; // 用来记录最小值的位置
        // 找到最小值节点的位置
        for (int i = 2; i < split.length; ++i) {
            int tmp = Integer.parseInt(split[i]);
            if (tmp == min) {
                minPos = i;
                break;
            }
        }
        List<String> path = new ArrayList<>(); // 用来存储路径
        back(split, minPos, path); // 调用回溯方法，找出路径

        // 输出路径
        for (int i = path.size() - 1; i >= 0; --i) {
            System.out.print(path.get(i)); // 按从根到叶的顺序输出路径
            if (i != 0) { // 如果不是最后一个节点，打印空格分隔
                System.out.print(" ");
            }
        }
    }
}